# To change this template, choose Tools | Templates
# and open the template in the editor.

class ZzBookAxis < Hash

  def initialize(center_axis_info_model = nil, query = "")
    self['axisid'] = 0
    self['axisbody'] = ''
    self['data'] = nil #array
    self['color'] = [242,73,166]
    self['is_focus'] = false
    @query = query

    if center_axis_info_model != nil
      @center_axis_info_model = center_axis_info_model
    end
  end
  
  def set_zzcells_from_models(center_axis_info_model)
    if center_axis_info_model != nil
      @center_axis_info_model = center_axis_info_model
    end
    return nil
  end

  def make_author_axis(hold_hash)
    #著者軸は"A"+著者ID
    self['axisid'] = "A" + @center_axis_info_model.author_id.to_s
    self['color'] = [101,86,191]
    #著者軸は著者そのものを軸名にする
    self['axisbody'] = Author.find(@center_axis_info_model.author_id).author

    if hold_hash['A'].include?(@center_axis_info_model.author_id.to_s)
      self['hold'] = true
    else
      self['hold'] = false
    end

    hold_sql = make_hold_sql_str(hold_hash)

    #authors1 = AsinInfo.find(:all,
    #  :order => 'title_rank desc',
    #  :conditions => ["#{hold_sql} author_id = ? and title_rank < ?" , @center_axis_info_model.author_id, @center_axis_info_model.title_rank],
    #  :limit => 2
    #)
    #authors2 = AsinInfo.find(:all,
    #  :order => 'title_rank asc',
    #  :conditions => ["#{hold_sql} author_id = ? and title_rank >= ?", @center_axis_info_model.author_id, @center_axis_info_model.title_rank],
    #  :limit => 3
    #)

    #authors1はdesc（降順）で取得したのでreverseで並び替え
    #authors = authors1.reverse + authors2

    authors = AsinInfo.find_by_sql(["select * from asin_infos where #{hold_sql} author_id = ? and title_rank >= (select coalesce(min(t1.title_rank),0) from (select * from asin_infos where #{hold_sql} author_id = ? and title_rank < ? order by title_rank desc limit 2) as t1 )  order by title_rank asc limit 0,5",@center_axis_info_model.author_id,@center_axis_info_model.author_id, @center_axis_info_model.title_rank])


    self['data']= fill_axis(authors,@center_axis_info_model)

  end

  def make_genre_axis(hold_hash)
    #ジャンル軸はG+ジャンルID
    self['axisid'] = "G" + @center_axis_info_model.genre.to_s
    self['color'] = [250,128,114]
    #ジャンル軸はジャンル名そのものを軸名にする
    self['axisbody'] = BrowseNode.find(:first,:conditions => ['node_number = ?',@center_axis_info_model.genre]).node_name


    if hold_hash['G'].include?(@center_axis_info_model.genre.to_s)
      self['hold'] = true
    else
      self['hold'] = false
    end


    hold_sql = make_hold_sql_str(hold_hash)

    #genres1 = AsinInfo.find(:all,
    #  :order => 'title_rank desc',
    #  #50音順
    #  :conditions => [" #{hold_sql} genre = ? and title_rank < ?", @center_axis_info_model.genre, @center_axis_info_model.title_rank],
    #  :limit => 2
    #)
    #genres2 = AsinInfo.find(:all,
    #  :order => 'title_rank asc',
    #  #とりあえずは売り上げ順(ほんとは50音順)
    #  :conditions => [" #{hold_sql} genre = ? and title_rank >= ?", @center_axis_info_model.genre, @center_axis_info_model.title_rank],
    #  :limit => 3
    #)

    #genres1はdesc（降順）で取得したのでreverseで並び替え
    #genres = genres1.reverse + genres2

    genres = AsinInfo.find_by_sql(["select * from asin_infos where #{hold_sql} genre = ? and title_rank >= (select coalesce(min(t1.title_rank),0) from (select * from asin_infos where #{hold_sql} genre = ? and title_rank < ? order by title_rank desc limit 2) as t1 ) order by title_rank asc limit 0,5",@center_axis_info_model.genre,@center_axis_info_model.genre, @center_axis_info_model.title_rank])


    self['data']= fill_axis(genres,@center_axis_info_model)

  end

  def make_similarity_axis(hold_hash)
    self['axisid'] = 1
    self['color'] = [255,158,61]
    self['axisbody'] = "おすすめ"
    if hold_hash[1]
      self['hold'] = true
    else
      self['hold'] = false
    end



    hold_sql = make_hold_sql_str(hold_hash)

    similarity_infos = SimilarityAsin.find(:all,
      :conditions => ["asin_id = ?",@center_axis_info_model.id]
    )

    similarity_infos_ids = Array.new()
    unless similarity_infos
      similarity_infos.each{|similarity_info|
        similarity_infos_ids.push(similarity_info.similarity_asin_id)
      }
    end
    unless similarity_infos_ids.include?(@center_axis_info_model.id)
      similarity_infos_ids.unshift(@center_axis_info_model.id)
    end
      
    similaritys = Array.new()
#    similarity_infos_ids.each{|similarity_infos_id|
#      begin
#        asin_info = AsinInfo.find(similarity_infos_id)
#        unless asin_info.title == nil
#          similaritys.push(asin_info)
#        end
#      rescue
#      end
#    }
    similaritys = AsinInfo.find(similarity_infos_ids,:conditions => ["title != ''"],:order => "title_rank")
    if similaritys.size == 0
      return false
    else
      self['data']= fill_axis(similaritys,@center_axis_info_model)
      return true
    end
  end

  def make_publisher_axis(hold_hash)
    #著者軸は"P"+出版社ID
    self['axisid'] = "P" + @center_axis_info_model.publisher_id.to_s
    self['color'] = [109,191,111]
    #出版社軸は出版社そのものを軸名にする
    self['axisbody'] = Publisher.find(@center_axis_info_model.publisher_id).publisher

    if hold_hash['P'].include?(@center_axis_info_model.publisher_id.to_s)
      self['hold'] = true
    else
      self['hold'] = false
    end

    hold_sql = make_hold_sql_str(hold_hash)

    #publishers1 = AsinInfo.find(:all,
    #  :order => 'title_rank desc',
    #  :conditions => [" #{hold_sql} publisher_id = ? and title_rank < ?", @center_axis_info_model.publisher_id, @center_axis_info_model.title_rank],
    #  :limit => 2
    #)
    #publishers2 = AsinInfo.find(:all,
    #  :order => 'title_rank asc',
    #  :conditions => [" #{hold_sql} publisher_id = ? and title_rank >= ?", @center_axis_info_model.publisher_id, @center_axis_info_model.title_rank],
    #  :limit => 3
    #)
    #publishers = publishers1.reverse + publishers2

    publishers = AsinInfo.find_by_sql(["select * from asin_infos where #{hold_sql} publisher_id = ? and title_rank >= (select coalesce(min(t1.title_rank),0) from (select * from asin_infos where #{hold_sql} publisher_id = ? and title_rank < ? order by title_rank desc limit 2) as t1 ) order by title_rank asc limit 0,5",@center_axis_info_model.publisher_id,@center_axis_info_model.publisher_id, @center_axis_info_model.title_rank])


    self['data']= fill_axis(publishers,@center_axis_info_model)
 
  end

  def make_sales_rank_axis(hold_hash)
    self['axisid'] = 3
    self['color'] = [135,183,242]
    self['axisbody'] = '売上ランキング'
    if hold_hash[3]
      self['hold'] = true
    else
      self['hold'] = false
    end




    hold_sql = make_hold_sql_str(hold_hash)

    #sales_ranks1 = AsinInfo.find(:all,
    #  :order => 'sales_rank desc',
    #  :conditions => [" #{hold_sql} sales_rank < ?",@center_axis_info_model.sales_rank],
    #  :limit => 2
    #)

    #sales_ranks2 = AsinInfo.find(:all,
    #  :order => 'sales_rank asc',
    #  :conditions => [" #{hold_sql} sales_rank >= ?",@center_axis_info_model.sales_rank],
    #  :limit => 3
    #)

    #sales_ranks = AsinInfo.find(:all,
    #  :order => 'sales_rank asc',
    #  :conditions => ["sales_rank < ? and sales_rank > ? and contents_type = 0",@center_axis_info_model.sales_rank + 3, @center_axis_info_model.sales_rank - 3]
    #)
    #sales_ranks = sales_ranks1.reverse + sales_ranks2
    sales_ranks = AsinInfo.find_by_sql(["select * from asin_infos where #{hold_sql} sales_rank >= (select coalesce(min(t1.sales_rank),0) from (select * from asin_infos where #{hold_sql} sales_rank < ? order by sales_rank desc limit 2)  as t1) order by sales_rank asc limit 0,5",@center_axis_info_model.sales_rank])

    self['data']= fill_axis(sales_ranks,@center_axis_info_model)
  end

  def make_total_reviews_rank_axis(hold_hash)
    self['axisid'] = 4
    self['color'] = [204,28,49]
    self['axisbody'] = 'レビュー数'
    if hold_hash[4]
      self['hold'] = true
    else
      self['hold'] = false
    end


    hold_sql = make_hold_sql_str(hold_hash)

    #total_reviews1 = AsinInfo.find(:all,
    #  :order => 'total_reviews_rank desc',
    #  :conditions => [" #{hold_sql} total_reviews_rank < ?", @center_axis_info_model.total_reviews_rank],
    #  :limit => 2
    #)
    #total_reviews2 = AsinInfo.find(:all,
    #  :order => 'total_reviews_rank asc',
    #  :conditions => [" #{hold_sql} total_reviews_rank >= ?", @center_axis_info_model.total_reviews_rank],
    #  :limit => 3
    #)
    #total_reviews = total_reviews1.reverse + total_reviews2
 
    total_reviews = AsinInfo.find_by_sql(["select * from asin_infos where #{hold_sql} total_reviews_rank >= (select coalesce(min(t1.total_reviews_rank),0) from (select * from asin_infos where #{hold_sql} total_reviews_rank < ? order by total_reviews_rank desc limit 2) as t1 ) order by total_reviews_rank asc limit 0,5",@center_axis_info_model.total_reviews_rank] )

    self['data']= fill_axis(total_reviews,@center_axis_info_model)
  end

  def make_average_rating_rank_axis(hold_hash)
    self['axisid'] = 5
    self['color'] = [55,173,191]
    self['axisbody'] = '評価レート'
    if hold_hash[5]
      self['hold'] = true
    else
      self['hold'] = false
    end


    hold_sql = make_hold_sql_str(hold_hash)

    #average_rating1 = AsinInfo.find(:all,
    #  :order => 'average_rating_rank desc',
    #  :conditions => [" #{hold_sql} average_rating_rank < ?", @center_axis_info_model.average_rating_rank],
    #  :limit => 2
    #)
    #average_rating2 = AsinInfo.find(:all,
    #  :order => 'average_rating_rank asc',
    #  :conditions => [" #{hold_sql} average_rating_rank >= ?", @center_axis_info_model.average_rating_rank],
    #  :limit => 3
    #)
    #average_ratings = average_rating1.reverse + average_rating2
    
    average_ratings = AsinInfo.find_by_sql(["select * from asin_infos where #{hold_sql} average_rating_rank >= (select coalesce(min(t1.average_rating_rank),0) from(select * from asin_infos where #{hold_sql} average_rating_rank < ? order by average_rating_rank desc limit 2) as t1 ) order by average_rating_rank asc limit 0,5",@center_axis_info_model.average_rating_rank] )
    self['data']= fill_axis(average_ratings,@center_axis_info_model)
  end

  def make_price_rank_axis(hold_hash)
    self['axisid'] = 6
    self['color'] = [191,99,125]
    self['axisbody'] = '価格'
    if hold_hash[6]
      self['hold'] = true
    else
      self['hold'] = false
    end

    hold_sql = make_hold_sql_str(hold_hash)

    #price1 = AsinInfo.find(:all,
    #  :order => 'price_rank desc',
    #  :conditions => [" #{hold_sql} price_rank < ?", @center_axis_info_model.price_rank],
    #  :limit => 2
    #)
    #price2 = AsinInfo.find(:all,
    #  :order => 'price_rank asc',
    #  :conditions => [" #{hold_sql} price_rank >= ?", @center_axis_info_model.price_rank],
    #  :limit => 3
    #)
    #prices = price1.reverse + price2

    prices = AsinInfo.find_by_sql(["select * from asin_infos where #{hold_sql} price_rank >= (select coalesce(min(t1.price_rank),0) from (select * from asin_infos where #{hold_sql} price_rank < ? order by price_rank desc limit 2) as t1 ) order by price_rank asc limit 0,5",@center_axis_info_model.price_rank] )
    self['data']= fill_axis(prices,@center_axis_info_model)
  end


  def make_number_ofpages_rank_axis(hold_hash)
    self['axisid'] = 7
    self['color'] = [160,191,110]
    self['axisbody'] = 'ページ数'
    if hold_hash[7]
      self['hold'] = true
    else
      self['hold'] = false
    end


    hold_sql = make_hold_sql_str(hold_hash)

    #page1 = AsinInfo.find(:all,
    #  :order => 'number_ofpages_rank desc',
    #  :conditions => [" #{hold_sql} number_ofpages_rank < ?", @center_axis_info_model.number_ofpages_rank],
    #  :limit => 2
    #)
    #page2 = AsinInfo.find(:all,
    #  :order => 'number_ofpages_rank asc',
    #  :conditions => [" #{hold_sql} number_ofpages_rank >= ?", @center_axis_info_model.number_ofpages_rank],
    #  :limit => 3
    #)
    #number_ofpages = page1.reverse + page2
    
    number_ofpages = AsinInfo.find_by_sql(["select * from asin_infos where #{hold_sql} number_ofpages_rank >= (select coalesce(min(t1.number_ofpages_rank),0) from (select * from asin_infos where #{hold_sql} number_ofpages_rank < ? order by number_ofpages_rank desc limit 2) as t1 ) order by number_ofpages_rank asc limit 0,5",@center_axis_info_model.number_ofpages_rank] )
    self['data']= fill_axis(number_ofpages,@center_axis_info_model)
  end

  def make_publication_date_rank_axis(hold_hash)
    self['axisid'] = 8
    self['color'] = [65,105,225]
    self['axisbody'] = '出版日'
    if hold_hash[8]
      self['hold'] = true
    else
      self['hold'] = false
    end


    hold_sql = make_hold_sql_str(hold_hash)

    #publication_date_rank1 = AsinInfo.find(:all,
    #  :order => 'publication_date_rank desc',
    #  :conditions => [" #{hold_sql} publication_date_rank < ?", @center_axis_info_model.publication_date_rank],
    #  :limit => 2
    # )
    #publication_date_rank2 = AsinInfo.find(:all,
    #  :order => 'publication_date_rank asc',
    #  :conditions => [" #{hold_sql} publication_date_rank >= ?", @center_axis_info_model.publication_date_rank],
    #  :limit => 3  
    #)
    #publication_date_ranks = publication_date_rank1.reverse + publication_date_rank2

    publication_date_ranks = AsinInfo.find_by_sql(["select * from asin_infos where #{hold_sql} publication_date_rank >= (select coalesce(min(t1.publication_date_rank),0) from (select * from asin_infos where #{hold_sql} publication_date_rank < ? order by publication_date_rank desc limit 2) as t1 ) order by publication_date_rank asc limit 0,5",@center_axis_info_model.publication_date_rank] )
    self['data']= fill_axis(publication_date_ranks,@center_axis_info_model)
  end

  def make_number_ofclicks_rank_axis(hold_hash)
    self['axisid'] = 9
    self['color'] = [255,182,193]
    self['axisbody'] = 'クリック数'
    if hold_hash[9]
      self['hold'] = true
    else
      self['hold'] = false
    end

    hold_sql = make_hold_sql_str(hold_hash)

    #number_ofclicks_rank1 = AsinInfo.find(:all,
    #  :order => 'number_ofclicks_rank desc',
    #  :conditions => [" #{hold_sql} number_ofclicks_rank < ?", @center_axis_info_model.number_ofclicks_rank],
    #  :limit => 2
    #)
    #number_ofclicks_rank2 = AsinInfo.find(:all,
    #  :order => 'number_ofclicks_rank asc',
    #  :conditions => [" #{hold_sql} number_ofclicks_rank >= ?", @center_axis_info_model.number_ofclicks_rank],
    #  :limit => 3
    #)
    #number_ofclicks_ranks = number_ofclicks_rank1.reverse + number_ofclicks_rank2
    
    number_ofclicks_ranks = AsinInfo.find_by_sql(["select * from asin_infos where #{hold_sql} number_ofclicks_rank >= (select coalesce(min(t1.number_ofclicks_rank),0) from (select * from asin_infos where #{hold_sql} number_ofclicks_rank < ? order by number_ofclicks_rank desc limit 2) as t1 ) order by number_ofclicks_rank  asc limit 0,5",@center_axis_info_model.number_ofclicks_rank])
    self['data']= fill_axis(number_ofclicks_ranks,@center_axis_info_model)
  end

  def make_dummy_axis(hold_hash)
    self['axisid'] = 99
    self['color'] = [109,191,111]
    self['axisbody'] = ""
    self['hold'] = false
    obj = Array.new
    obj.push(@center_axis_info_model)
    self['data']= fill_axis(obj,@center_axis_info_model)
  end

  def fill_axis(objects,center_object)
    center_cell_index  = 0
    objects.each_with_index{|v,i|
      if v.id == center_object.id
        center_cell_index = i
        break
      end
    }
    last_index = objects.size - 1

    filled_axis_data = Array.new
    #中心セルが配列の先頭にある
    # 先頭２個を空のセルで埋め、残り３個を取得したセルで埋める
    if center_cell_index == 0
      #objects = objects[0..2]
      filled_axis_data.push(ZzBookCell.new)
      filled_axis_data.push(ZzBookCell.new)
      objects[0..2].each{|author|
        filled_axis_data.push(ZzBookCell.new(author))
      }
      if objects.size == 1
        filled_axis_data.push(ZzBookCell.new)
        filled_axis_data.push(ZzBookCell.new)
      elsif objects.size == 2
        filled_axis_data.push(ZzBookCell.new)
      end

    elsif center_cell_index == 1
      filled_axis_data.push(ZzBookCell.new)
      objects[0..3].each{|author|
        filled_axis_data.push(ZzBookCell.new(author))
      }
      if objects.size == 2
        filled_axis_data.push(ZzBookCell.new)
        filled_axis_data.push(ZzBookCell.new)
      elsif objects.size == 3
        filled_axis_data.push(ZzBookCell.new)
      end
    elsif center_cell_index == last_index -1
      objects[(last_index-3)..last_index].each{|author|
        filled_axis_data.push(ZzBookCell.new(author))
      }
      filled_axis_data.push(ZzBookCell.new)

    elsif center_cell_index == last_index
      objects[(last_index-2)..last_index].each{|author|
        filled_axis_data.push(ZzBookCell.new(author))
      }
      filled_axis_data.push(ZzBookCell.new)
      filled_axis_data.push(ZzBookCell.new)
    else
      objects[(center_cell_index-2)..(center_cell_index+2)].each{|author|
        filled_axis_data.push(ZzBookCell.new(author))
      }
    end

    #RAILS_DEFAULT_LOGGER.debug filled_axis_data
    return filled_axis_data
    
  end


  def make_query_axis(hold_hash)
    #クエリ軸はQ+クエリID
    @query.strip_with_full_size_space!
    q = Query.find(:first,:conditions => {:query => @query})
    if q == nil
      q = Query.new({:query => @query})
      q.save
      q = Query.find(:first,:order => "id desc")
    end
    self['axisid'] = "Q" + q.id.to_s
    self['color'] = [65,105,255]
    self['axisbody'] = @query
    if hold_hash['Q'].include?(q.id.to_s)
      self['hold'] = true
    else
      self['hold'] = false
    end

    hold_sql = make_hold_sql_str(hold_hash)

    query_search_results = AsinInfo.find(:all,
                                         :order => "match(title) against('*D+ #{@query}' IN BOOLEAN MODE)",
                                         :conditions => ["#{hold_sql} contents_type = 0 and sales_rank != 0 and match(title) against('*D+ #{@query}' in boolean mode)"]
    )
    
    center_axis_info_model_index = 0
    query_search_results.each_with_index{|result_model,i|
      if result_model.id == @center_axis_info_model.id
        center_axis_info_model_index = i
      end
    }

    start_index = center_axis_info_model_index -2
    if (center_axis_info_model_index -2)  < 0
      start_index = 0
    end
    end_index = center_axis_info_model_index + 2


    query_search_results = query_search_results[start_index,end_index]
    query_search_results.reject! {|x| x == nil }

    self['data']= fill_axis(query_search_results,@center_axis_info_model)
  end


  def make_hold_sql_str(hold_hash)

    ret_str = ""

    author_hold_ids = hold_hash['A']
    publisher_hold_ids = hold_hash['P']
    genre_hold_ids = hold_hash['G']
    query_hold = hold_hash['Q']
    unless author_hold_ids.size == 0
      author_hold_ids.each{|author_hold_id|
        ret_str << "author_id = #{author_hold_id} and "
      }
    end
    unless publisher_hold_ids.size == 0
      publisher_hold_ids.each{|publisher_hold_id|
        ret_str << "publisher_id = #{publisher_hold_id} and "
      }
    end
    unless genre_hold_ids.size == 0
      genre_hold_ids.each{|genre_hold_id|
        ret_str << "genre = #{genre_hold_id} and "
      }
    end
    unless query_hold.size == 0
      query_hold.each{|queryid|
        q = Query.find(queryid.to_i)
        ret_str << "match(title) against('#{q.query}') and "
      }
    end


    return ret_str
  end

end

def make_query_match_sql(query)
  ret_str = ""
  if query == "" ||  query == nil
    puts "test"
    return ret_str
  end
  ret_str = "and match(title) against('#{query}')"
end


